#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
应用程序框架分析器 - API路由
包含所有API端点定义
"""

import os
import json
import uuid
import shutil
from pathlib import Path
from datetime import datetime

from flask import request, jsonify, send_from_directory
from werkzeug.utils import secure_filename

from .app import app, tasks
from .task_handler import analyze_task
from .config import (
    UPLOAD_FOLDER, REPORT_FOLDER, ALLOWED_EXTENSIONS, 
    MAX_CONTENT_LENGTH, AUTO_CLEANUP_UPLOADS, 
    AUTO_CLEANUP_REPORTS, CLEANUP_AFTER_DAYS
)

# 确保上传和报告目录存在
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
os.makedirs(REPORT_FOLDER, exist_ok=True)

# 配置应用
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = MAX_CONTENT_LENGTH  # 使用配置文件中的值


def allowed_file(filename):
    """检查文件是否允许上传"""
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


@app.route('/api/health', methods=['GET'])
def health_check():
    """健康检查端点"""
    # 添加最大上传大小信息
    max_size_gb = app.config.get('MAX_CONTENT_LENGTH', 0) / (1024 * 1024 * 1024)
    return jsonify({
        'status': 'ok',
        'timestamp': datetime.now().isoformat(),
        'version': '1.0.0',
        'max_upload_size_gb': round(max_size_gb, 2)
    })


@app.route('/api/config', methods=['GET'])
def get_system_config():
    """获取系统配置信息接口"""
    return jsonify({
        'max_upload_size': MAX_CONTENT_LENGTH,
        'max_upload_size_human': f"{MAX_CONTENT_LENGTH / (1024 * 1024 * 1024):.1f} GB",
        'allowed_file_types': list(ALLOWED_EXTENSIONS),
        'auto_cleanup_uploads': AUTO_CLEANUP_UPLOADS,
        'auto_cleanup_reports': AUTO_CLEANUP_REPORTS,
        'cleanup_after_days': CLEANUP_AFTER_DAYS
    })


@app.route('/api/upload', methods=['POST'])
def upload_file():
    """
    上传应用文件接口
    
    请求参数:
    - file: 要上传的应用文件
    - platform: (可选) 指定平台类型，如不指定则自动检测
    
    返回:
    - task_id: 分析任务ID，用于查询分析状态和结果
    """
    # 检查请求中是否包含文件
    if 'file' not in request.files:
        return jsonify({'error': 'No file part'}), 400
    
    file = request.files['file']
    if file.filename == '':
        return jsonify({'error': 'No selected file'}), 400
    
    if not file or not allowed_file(file.filename):
        return jsonify({'error': f'File type not allowed. Allowed types: {", ".join(ALLOWED_EXTENSIONS)}'}), 400
    
    # 保存上传的文件
    filename = secure_filename(file.filename)
    task_id = str(uuid.uuid4())
    task_upload_dir = Path(app.config['UPLOAD_FOLDER']) / task_id
    os.makedirs(task_upload_dir, exist_ok=True)
    
    file_path = task_upload_dir / filename
    file.save(file_path)
    
    # 获取平台类型，不指定则自动检测
    platform = request.form.get('platform', 'auto')
    
    # 创建任务记录
    tasks[task_id] = {
        'status': 'pending',
        'file_path': str(file_path),
        'platform': platform,
        'created_at': datetime.now().isoformat(),
        'updated_at': datetime.now().isoformat(),
        'result': None,
        'error': None
    }
    
    # 启动异步分析任务
    import threading
    threading.Thread(target=analyze_task, args=(task_id, file_path, platform, REPORT_FOLDER)).start()
    
    return jsonify({
        'task_id': task_id,
        'status': 'pending',
        'message': 'File uploaded and analysis started'
    })


@app.route('/api/tasks/<task_id>', methods=['GET'])
def get_task_status(task_id):
    """
    获取任务状态接口
    
    URL参数:
    - task_id: 任务ID
    
    返回:
    - 任务状态和结果信息
    """
    if task_id not in tasks:
        return jsonify({'error': 'Task not found'}), 404
    
    task = tasks[task_id]
    response = {
        'task_id': task_id,
        'status': task['status'],
        'created_at': task['created_at'],
        'updated_at': task['updated_at'],
    }
    
    # 如果任务完成，包含结果
    if task['status'] == 'completed' and task['result']:
        # 确保框架信心值为正确的百分比格式(0-100)
        frameworks = task['result']['frameworks']
        for fw in frameworks:
            if isinstance(fw['confidence'], float) and 0 <= fw['confidence'] <= 1:
                fw['confidence'] = int(fw['confidence'] * 100)
                
        response['result'] = {
            'summary': task['result']['summary'],
            'frameworks_count': len(frameworks),
            'report_url': f"/api/reports/{task_id}",
            'frameworks': frameworks
        }
    
    # 如果任务失败，包含错误信息
    if task['status'] == 'failed' and task['error']:
        response['error'] = task['error']['message']
    
    return jsonify(response)


@app.route('/api/reports/<task_id>', methods=['GET'])
def get_report(task_id):
    """
    获取分析报告接口
    
    URL参数:
    - task_id: 任务ID
    - format: (可选) 报告格式，支持html、json
    
    返回:
    - 分析报告文件
    """
    if task_id not in tasks:
        return jsonify({'error': 'Task not found'}), 404
    
    task = tasks[task_id]
    if task['status'] != 'completed':
        return jsonify({'error': 'Task not completed yet'}), 400
    
    report_format = request.args.get('format', 'html')
    report_dir = Path(REPORT_FOLDER) / task_id
    
    if report_format == 'json':
        # 返回JSON格式的结果
        json_file = report_dir / 'result.json'
        if not json_file.exists():
            return jsonify({'error': 'JSON report not found'}), 404
        
        with open(json_file, 'r', encoding='utf-8') as f:
            report_data = json.load(f)
        
        return jsonify(report_data)
    
    elif report_format == 'html':
        # 返回HTML格式的报告
        html_files = list(report_dir.glob('*.html'))
        if not html_files:
            html_files = list(report_dir.glob('report*/*.html'))
        
        if not html_files:
            return jsonify({'error': 'HTML report not found'}), 404
        
        # 返回第一个HTML文件
        html_file = html_files[0]
        return send_from_directory(html_file.parent, html_file.name)
    
    else:
        return jsonify({'error': 'Unsupported report format'}), 400


@app.route('/api/frameworks', methods=['GET'])
def get_supported_frameworks():
    """
    获取支持的框架列表接口
    
    返回:
    - 各平台支持检测的框架列表
    """
    # 从各分析器中获取支持的框架
    from src.analyzers.android import AndroidAnalyzer
    from src.analyzers.ios import IOSAnalyzer
    from src.analyzers.windows import WindowsAnalyzer
    
    frameworks = {
        'android': list(AndroidAnalyzer.FRAMEWORK_SIGNATURES.keys()),
        'ios': list(IOSAnalyzer.FRAMEWORK_SIGNATURES.keys()),
        'windows': list(WindowsAnalyzer.FRAMEWORK_SIGNATURES.keys()),
    }
    
    return jsonify({
        'supported_frameworks': frameworks,
        'total_count': sum(len(fws) for fws in frameworks.values())
    })


@app.route('/api/cleanup', methods=['POST'])
def cleanup_task():
    """
    清理任务文件接口
    
    请求参数:
    - task_id: 要清理的任务ID
    
    返回:
    - 清理操作结果
    """
    data = request.json
    if not data or 'task_id' not in data:
        return jsonify({'error': 'task_id is required'}), 400
    
    task_id = data['task_id']
    if task_id not in tasks:
        return jsonify({'error': 'Task not found'}), 404
    
    # 清理上传文件
    upload_dir = Path(app.config['UPLOAD_FOLDER']) / task_id
    if upload_dir.exists():
        shutil.rmtree(upload_dir)
    
    # 如果指定了也清理报告文件
    if data.get('include_reports', False):
        report_dir = Path(REPORT_FOLDER) / task_id
        if report_dir.exists():
            shutil.rmtree(report_dir)
    
    # 从任务列表中移除
    if data.get('remove_task', False):
        tasks.pop(task_id, None)
    
    return jsonify({
        'success': True,
        'message': f'Task {task_id} files cleaned up successfully'
    }) 
